package com.imut.lagain.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.imut.lagain.exception.BusinessException;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.regex.Pattern;

/**
 * 数据验证工具类
 */
public class ValidationUtil {
    private static final Logger log = LoggerFactory.getLogger(ValidationUtil.class);
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
    private static final Pattern EMAIL_PATTERN = Pattern.compile(
        "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
    private static final Pattern PASSWORD_PATTERN = Pattern.compile(
        "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d@$!%*#?&]{8,}$");
    private static final Pattern USERNAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_]{3,20}$");
    private static final Pattern NICKNAME_PATTERN = Pattern.compile("^[\\u4e00-\\u9fa5a-zA-Z0-9\\s]{1,50}$");
    
    /**
     * 验证字符串不为空
     */
    public static void validateNotEmpty(String value, String fieldName) {
        if (!StringUtils.hasText(value)) {
            throw new BusinessException.InvalidParameterException(fieldName + "不能为空");
        }
    }
    
    /**
     * 验证对象不为空
     */
    public static void validateNotNull(Object value, String fieldName) {
        if (value == null) {
            throw new BusinessException.InvalidParameterException(fieldName + "不能为空");
        }
    }
    
    /**
     * 验证字符串长度
     */
    public static void validateLength(String value, int minLength, int maxLength, String fieldName) {
        if (value == null) {
            return;
        }
        
        int length = value.length();
        if (length < minLength || length > maxLength) {
            throw new BusinessException.InvalidParameterException(
                String.format("%s长度必须在%d-%d之间", fieldName, minLength, maxLength));
        }
    }
    
    /**
     * 验证数值范围
     */
    public static void validateRange(Number value, Number min, Number max, String fieldName) {
        if (value == null) {
            return;
        }
        
        double doubleValue = value.doubleValue();
        double minValue = min.doubleValue();
        double maxValue = max.doubleValue();
        
        if (doubleValue < minValue || doubleValue > maxValue) {
            throw new BusinessException.InvalidParameterException(
                String.format("%s必须在%s-%s之间", fieldName, min, max));
        }
    }
    
    /**
     * 验证手机号
     */
    public static void validatePhoneNumber(String phoneNumber) {
        if (!StringUtils.hasText(phoneNumber)) {
            return;
        }
        
        if (!PHONE_PATTERN.matcher(phoneNumber).matches()) {
            throw new BusinessException.InvalidParameterException("手机号格式不正确");
        }
    }
    
    /**
     * 验证手机号（别名方法）
     */
    public static void validatePhone(String phone) {
        validatePhoneNumber(phone);
    }
    
    /**
     * 验证邮箱
     */
    public static void validateEmail(String email) {
        if (!StringUtils.hasText(email)) {
            return;
        }
        
        if (!EMAIL_PATTERN.matcher(email).matches()) {
            throw new BusinessException.InvalidParameterException("邮箱格式不正确");
        }
    }
    
    /**
     * 验证密码强度
     */
    public static void validatePassword(String password) {
        if (!StringUtils.hasText(password)) {
            throw new BusinessException.InvalidParameterException("密码不能为空");
        }
        
        if (!PASSWORD_PATTERN.matcher(password).matches()) {
            throw new BusinessException.InvalidParameterException(
                "密码必须至少8位，包含字母和数字");
        }
    }
    
    /**
     * 验证用户名
     */
    public static void validateUsername(String username) {
        validateNotEmpty(username, "用户名");
        
        if (!USERNAME_PATTERN.matcher(username).matches()) {
            throw new BusinessException.InvalidParameterException(
                "用户名必须是3-20位的字母、数字或下划线");
        }
    }
    
    /**
     * 验证昵称
     */
    public static void validateNickname(String nickname) {
        if (!StringUtils.hasText(nickname)) {
            return;
        }
        
        if (!NICKNAME_PATTERN.matcher(nickname).matches()) {
            throw new BusinessException.InvalidParameterException(
                "昵称必须是1-50位的中文、字母、数字或空格");
        }
    }
    
    /**
     * 验证时间范围
     */
    public static void validateTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime != null && endTime != null) {
            if (startTime.isAfter(endTime)) {
                throw new BusinessException.InvalidParameterException("开始时间不能晚于结束时间");
            }
        }
    }
    
    /**
     * 验证未来时间
     */
    public static void validateFutureTime(LocalDateTime time, String fieldName) {
        if (time != null && time.isBefore(LocalDateTime.now())) {
            throw new BusinessException.InvalidParameterException(fieldName + "必须是未来时间");
        }
    }
    
    /**
     * 验证过去时间
     */
    public static void validatePastTime(LocalDateTime time, String fieldName) {
        if (time != null && time.isAfter(LocalDateTime.now())) {
            throw new BusinessException.InvalidParameterException(fieldName + "必须是过去时间");
        }
    }
    
    /**
     * 验证分页参数
     */
    public static void validatePageParams(Integer page, Integer size) {
        if (page != null && page < 0) {
            throw new BusinessException.InvalidParameterException("页码不能小于0");
        }
        
        if (size != null) {
            if (size <= 0) {
                throw new BusinessException.InvalidParameterException("页面大小必须大于0");
            }
            if (size > 100) {
                throw new BusinessException.InvalidParameterException("页面大小不能超过100");
            }
        }
    }
    
    /**
     * 验证ID
     */
    public static void validateId(Long id, String fieldName) {
        if (id == null || id <= 0) {
            throw new BusinessException.InvalidParameterException(fieldName + "必须是正整数");
        }
    }
    
    /**
     * 验证枚举值
     */
    public static <T extends Enum<T>> void validateEnum(String value, Class<T> enumClass, String fieldName) {
        if (!StringUtils.hasText(value)) {
            return;
        }
        
        try {
            Enum.valueOf(enumClass, value.toUpperCase());
        } catch (IllegalArgumentException e) {
            throw new BusinessException.InvalidParameterException(
                fieldName + "值不正确，允许的值: " + java.util.Arrays.toString(enumClass.getEnumConstants()));
        }
    }
    
    /**
     * 验证URL格式
     */
    public static void validateUrl(String url, String fieldName) {
        if (!StringUtils.hasText(url)) {
            return;
        }
        
        try {
            java.net.URI uri = java.net.URI.create(url);
            if (uri.getScheme() == null) {
                throw new java.net.MalformedURLException("Missing scheme");
            }
        } catch (IllegalArgumentException e) {
            throw new BusinessException.InvalidParameterException(fieldName + "格式不正确");
        } catch (java.net.MalformedURLException e) {
            throw new BusinessException.InvalidParameterException(fieldName + "格式不正确");
        }
    }
    
    /**
     * 验证文件扩展名
     */
    public static void validateFileExtension(String fileName, String[] allowedExtensions, String fieldName) {
        if (!StringUtils.hasText(fileName)) {
            throw new BusinessException.InvalidParameterException(fieldName + "不能为空");
        }
        
        String extension = getFileExtension(fileName).toLowerCase();
        
        for (String allowed : allowedExtensions) {
            if (allowed.toLowerCase().equals(extension)) {
                return;
            }
        }
        
        throw new BusinessException.InvalidParameterException(
            fieldName + "扩展名不支持，允许的扩展名: " + String.join(", ", allowedExtensions));
    }
    
    /**
     * 获取文件扩展名
     */
    private static String getFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex > 0 && lastDotIndex < fileName.length() - 1) {
            return fileName.substring(lastDotIndex);
        }
        return "";
    }
    
    /**
     * 验证JSON格式
     */
    public static void validateJson(String json, String fieldName) {
        if (!StringUtils.hasText(json)) {
            return;
        }
        
        try {
            com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
            mapper.readTree(json);
        } catch (Exception e) {
            throw new BusinessException.InvalidParameterException(fieldName + "不是有效的JSON格式");
        }
    }
    
    /**
     * 验证IP地址格式
     */
    public static void validateIpAddress(String ip, String fieldName) {
        if (!StringUtils.hasText(ip)) {
            return;
        }
        
        Pattern ipPattern = Pattern.compile(
            "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
        
        if (!ipPattern.matcher(ip).matches()) {
            throw new BusinessException.InvalidParameterException(fieldName + "格式不正确");
        }
    }
}
